package tests

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/henrylee2cn/goutil"
	"log"
	"my_gin/utils"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	T "time"
)

type loginForm struct {
	User     string `form:"user" binding:"required"`
	Password string `form:"password" binding:"required"`
	Code     string `form:"code" binding:"required"`
}

// Login 用户登录 POST 提交
func Login(c *gin.Context) {
	var form loginForm
	if c.ShouldBindWith(&form, binding.Form) != nil {
		c.String(http.StatusUnauthorized, "所有输入框必填！")
		return
	}
	if len(form.Code) != 4 {
		c.String(http.StatusUnauthorized, "验证码长度必须 4 位")
		return
	}
	captcha, err := c.Cookie("captcha")
	if err != nil {
		c.String(http.StatusUnauthorized, "Cookie 丢失！")
		return
	}
	cookie, err := url.ParseQuery(captcha)
	if err != nil {
		c.String(http.StatusUnauthorized, "Cookie 为空或格式错误！")
		return
	}
	timeArr, ok := cookie["time"]
	if !ok || len(timeArr) != 1 {
		c.String(http.StatusUnauthorized, "Cookie 错误（没有 time 信息）！")
		return
	}
	time, err := strconv.ParseInt(timeArr[0], 10, 64)
	if err != nil {
		c.String(http.StatusUnauthorized, "Cookie 错误（time 不是有效时间戳）！")
		return
	}
	timeNow := T.Now().Unix()
	if timeNow < time || timeNow-time > 300 {
		c.String(http.StatusUnauthorized, "Cookie 错误（time 失效）！")
		return
	}
	signArr, ok := cookie["sign"]
	if !ok || len(signArr) != 1 {
		c.String(http.StatusUnauthorized, "Cookie 错误（没有 sign 信息）！")
		return
	}
	key, ok := utils.GetEnvByKey("APP_KEY")
	if !ok {
		log.Fatal("请在 .env 配置 APP_KEY")
	}
	sign := fmt.Sprintf("%v%v%v", strings.ToLower(form.Code), key, time)
	if goutil.Md5(goutil.StringToBytes(sign)) != signArr[0] {
		c.String(http.StatusUnauthorized, "验证码错误！")
		return
	}
	userPasswordMd5, ok := utils.GetEnvByKey("USER_PASSWORD")
	if !ok {
		log.Fatal("请在 .env 配置 USER_PASSWORD")
	}
	userPassword := fmt.Sprintf("%v%v", form.User, form.Password)
	if goutil.Md5(goutil.StringToBytes(userPassword)) != userPasswordMd5 {
		c.String(http.StatusUnauthorized, "用户名或密码错误！")
		return
	}
	c.String(http.StatusOK, "登录成功！")
}
